﻿// Spun AJAX Framework
// Copyright (C) 2008 Blake Hegerle
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.Net;
using System.IO;
using System.Threading;
using Spun.Communications.Hosting;

namespace TestFramework.UnitTests.Hosting
{
    [TestFixture]
    public class TestHosting
    {
        public class FooHost : Host
        {
            public FooHost(string HostString, short Port, string VirtualDirectory, string Greeting)
                : base(HostString, Port, VirtualDirectory)
            {
                this.Greeting = Greeting;
            }

            protected override void HandleRequest(HttpListenerContext Context)
            {
                using (StreamWriter Writer = new StreamWriter(Context.Response.OutputStream))
                    Writer.Write(Greeting);
            }

            private string Greeting;
        }

        public class TextServer : IServer
        {
            public TextServer(string Text)
            {
                this.Text = Text;
            }

            #region IServer Members

            public void ProcessRequest(HttpListenerContext Context, string j)
            {
                using (StreamWriter Writer = new StreamWriter(Context.Response.OutputStream))
                    Writer.Write(Text);
            }

            #endregion

            private string Text;
        }

        [Test]
        public void SimpleWebHostTest()
        {
            string Foo = "foo", Bar = "bar";
            string VDirBase = "SpunUnitTest/";

            using (new FooHost(Host.HOST_WILDCARD, 80, VDirBase + Foo, Foo))
            using (new FooHost(Host.HOST_WILDCARD, 80, VDirBase + Bar, Bar))
            {
                CheckHttpBody(Foo, VDirBase);
                CheckHttpBody(Bar, VDirBase);
            }
        }

        [Test]
        public void NestedWebHostTest()
        {
            string Foo = "foo", Bar = "bar";
            string VDirBase = "SpunUnitTest";

            string FooVDir = "";
            string BarVDir = Bar;

            var Servers = new Dictionary<string, IServer>();

            Servers[FooVDir] = new TextServer(Foo);
            Servers[BarVDir] = new TextServer(Bar);

            using (new ServerHost(Host.HOST_WILDCARD, 80, VDirBase, Servers))
            {
                Assert.AreEqual(Foo, BodyOf(VDirBase + '/' + FooVDir), "Did not get the expected HTTP body from " + FooVDir);
                Assert.AreEqual(Bar, BodyOf(VDirBase + '/' + BarVDir), "Did not get the expected HTTP body from " + BarVDir);
            }
        }

        private static void CheckHttpBody(string VDirAndHttpBody, string VDirBase)
        {
            Assert.AreEqual(VDirAndHttpBody, BodyOf(VDirBase + VDirAndHttpBody), "Did not get the expected HTTP body from " + VDirBase + VDirAndHttpBody);
        }

        private static string BodyOf(string VDir)
        {
            WebRequest Request = HttpWebRequest.Create("http://localhost/" + VDir);

            string Body;
            using (StreamReader Reader = new StreamReader(Request.GetResponse().GetResponseStream()))
                Body = Reader.ReadToEnd();

            Console.WriteLine("Got HTTP body: " + Body);

            return Body;
        }
    }
}
